package com.yazi.mxz.common.service.impl;

import java.text.SimpleDateFormat;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.myframework.smhj.common.exception.MyEntityNotExistsException;
import com.myframework.smhj.common.exception.MyException;
import com.myframework.smhj.common.exception.MyIllegalArgumentException;
import com.myframework.smhj.common.exception.MyNoPermissionException;
import com.myframework.smhj.common.tool.DateUtil;
import com.myframework.smhj.hibernate.dao.BasicService;
import com.myframework.smhj.hibernate.dao.Dao;
import com.yazi.mxz.common.MyUtil;
import com.yazi.mxz.common.db.dao.StoreGoodsDao;
import com.yazi.mxz.common.db.dao.StoreRestockDao;
import com.yazi.mxz.common.db.dao.StoreRestockGoodsDao;
import com.yazi.mxz.common.entity.ValueFactory;
import com.yazi.mxz.common.entity.beans.Store;
import com.yazi.mxz.common.entity.beans.StoreGoods;
import com.yazi.mxz.common.entity.beans.StoreRestock;
import com.yazi.mxz.common.entity.beans.StoreRestockGoods;
import com.yazi.mxz.common.entity.enums.StoreRestockGoodsType;
import com.yazi.mxz.common.service.StoreRestockService;

@Service("storeRestockService")
public class StoreRestockServiceImpl extends BasicService<StoreRestock> implements StoreRestockService {
	private static Logger log = LoggerFactory.getLogger(StoreRestockServiceImpl.class);
	
	@Resource
	StoreRestockDao storeRestockDao;
	@Resource
	StoreGoodsDao storeGoodsDao;
	@Resource
	StoreRestockGoodsDao storeRestockGoodsDao;
	
	@Override
	protected Dao<StoreRestock> getDao() {
		return storeRestockDao;
	}
	
	@Override
	public StoreRestock addOrEditBystore(Store store, String operator, StoreRestock storeRestock, 
			List<StoreRestockGoods> storeRestockGoodses) throws MyException {
		
		if (null == storeRestockGoodses || storeRestockGoodses.size() == 0) {
			throw new MyIllegalArgumentException("需要至少指定一个进货商品");
		}
		
		Long restockId = storeRestock.getRestockId();
		StoreRestock dsr = null;// destStoreRestock
		
		if (null == restockId || restockId <= 0) {// 添加
			
			log.debug("addOrEditBystore->add: storeId={}", store.getStoreId());
			
			ValueFactory.validate(storeRestock);
			
			SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
			storeRestock.setCode("RK" + sdf.format(DateUtil.getTimeStamp())); // 进货单编号
			storeRestock.setStore(store);
			storeRestock.setAdder(operator);
			storeRestock.setAddTime(DateUtil.getTimeStamp()); // 添加时间
			storeRestock.setRestockId(null);
			
			dsr = storeRestockDao.persist(storeRestock);
			
		} else {// 更新
			
			log.debug("addOrEditBystore->edit: storeId={},restockId={}", store.getStoreId(), restockId);
			
			dsr = storeRestockDao.get(restockId);
			
			if (null == dsr) {
				throw new MyEntityNotExistsException();
			}
			if (!dsr.getStore().equals(store)) {
				throw new MyNoPermissionException();
			}
			
			if (dsr.getIsChecked()) {
				throw new MyNoPermissionException("当前状态不允许该操作");
			}
			
			// 删除原进货单上的进货商品
			storeRestockGoodsDao.deleteByRestockId(restockId);
			
			// 防止篡改以下信息
			storeRestock.setAdder(null);
			storeRestock.setAddTime(null);
			storeRestock.setCode(null);
			
			ValueFactory.combine(storeRestock, dsr);
			
			storeRestockDao.merge(dsr);
			
		}
		
		// 添加进货商品
		setStoreRestockGoods(dsr, storeRestockGoodses);
		
		// 库存入库
		if (dsr.getIsChecked()) {
			checkByChecker(operator, dsr);
		}
		
		return dsr;
		
	}

	@Override
	public StoreRestock editToCheckedByStore(Store store, long restockId, 
			String checker) throws MyException {
		log.debug("editToCheckedByStore: storeId={},restockId={},checker={}", 
				new Object[]{store.getStoreId(), restockId, checker});
		
		StoreRestock storeRestock = storeRestockDao.get(restockId);
		if (null == storeRestock) {
			throw new MyEntityNotExistsException();
		}
		if (!storeRestock.getStore().equals(store)) {
			throw new MyNoPermissionException();
		}
		
		checkByChecker(checker, storeRestock);
		
		return storeRestock;
	}
	

	/**
	 * 添加进货单商品
	 * @param storeRestock 进货单(游离对象)
	 * @param storeRestockGoodses 进货单商品(表单对象)
	 */
	private void setStoreRestockGoods(StoreRestock storeRestock, 
			List<StoreRestockGoods> storeRestockGoodses) throws MyException {
		StoreGoods sg = null;
		for (StoreRestockGoods srg : storeRestockGoodses) {
			
			sg = storeGoodsDao.get(srg.getId().getStoreGoodsId()); 
			
			if (null == sg) {
				throw new MyEntityNotExistsException();
			}
			if (!sg.getStore().equals(storeRestock.getStore())) {
				throw new MyNoPermissionException();
			}
			
			ValueFactory.validate(srg);
			srg.getId().setRestockId(storeRestock.getRestockId());
			srg.setStoreGoods(sg);
			srg = storeRestockGoodsDao.persist(srg);
			storeRestock.getStoreRestockGoodses().add(srg);
		}
	}
	
	/**
	 * 进货单入库
	 * @param checker 操作人
	 * @param storeRestock 进货单(游离对象)
	 */
	private void checkByChecker(String checker, StoreRestock storeRestock) {
		
		// 更新进货单的“入库状态”、“入库人”和“入库时间”信息
		storeRestock.setIsChecked(true);
		storeRestock.setChecker(checker);
		storeRestock.setCheckTime(DateUtil.getTimeStamp());
		storeRestock = storeRestockDao.merge(storeRestock);
		
		// 商品库存入库
		for (StoreRestockGoods srg : storeRestock.getStoreRestockGoodses()) {
			checkStoreRestockGoods(srg);
		}
		
	}
	
	/**
	 * 库存入库
	 * @param srg 进货单商品(游离对象)
	 */
	private void checkStoreRestockGoods(StoreRestockGoods srg) {
		StoreGoods sg = srg.getStoreGoods();
		
		srg.setIsChecked(true);
		srg.setPrevStock(sg.getStock());
		srg.setPrevSelfCost(sg.getSelfCost());
		storeRestockGoodsDao.merge(srg);
		
		// 店铺商品最终库存、进货价
		Float restock;
		Float selfCost;
		
		if (srg.getType() == StoreRestockGoodsType.LOSS.ordinal()) { // 入库方式为“损耗”
			
			restock = srg.getRestock();
			selfCost = srg.getSelfCost() / srg.getRestock();
			
		} else { // 入库方式为“合并”
			
			restock = sg.getStock() + srg.getRestock(); // 库存 = 原来库存 + 进货量
			selfCost = (sg.getStock() * sg.getSelfCost() + srg.getSelfCost()) 
					/ restock; // 进货价 = (原来库存 * 原来成本 + 进货价) / 库存
			
		}
		
		// 折算库存
		if (null != sg.getSellUnit()) {
			sg.setStockConvert(MyUtil.numRoundDown(restock / sg.getUnitConvert(), 0).floatValue());
		} else {
			sg.setStockConvert(MyUtil.numRoundDown(restock, 2).floatValue());
		}
		
		sg.setStock(MyUtil.numRoundDown(restock, 2).floatValue());
		sg.setSelfCost(MyUtil.numRoundDown(selfCost, 2).floatValue());
		
		storeGoodsDao.merge(sg);
	}
	

	@Override
	public void removeByStore(Store store, long restockId) throws MyException {
		log.debug("removeByStore：storeId={},restockId={}", store.getStoreId(), restockId);
		
		StoreRestock storeRestock = storeRestockDao.get(restockId);
		if (null == storeRestock || !storeRestock.getStore().equals(store)) {
			return;
		}
		
		if (storeRestock.getIsChecked()) {
			throw new MyNoPermissionException("当前状态不允许该操作");
		}
		
		// 删除进货单上的进货商品
		storeRestockGoodsDao.deleteByRestockId(restockId);
		// 删除进货单
		storeRestockDao.delete(storeRestock);
		
	}

}
